package com.wd.pub.tools.service.impl;

import cn.hutool.core.lang.Console;
import cn.hutool.json.JSONUtil;
import com.wd.cloud.commons.util.NetUtil;
import com.wd.pub.tools.dto.OrgIpDTO;
import com.wd.pub.tools.entity.uoserver.OrgIp;
import com.wd.pub.tools.repository.spischolar.TOrgRepository;
import com.wd.pub.tools.repository.uoserver.OrgIpRepository;
import com.wd.pub.tools.service.AsyncIpService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import sun.net.util.IPAddressUtil;

import java.math.BigInteger;
import java.util.*;

/**
 * @Author: He Zhigang
 * @Date: 2019/5/30 17:52
 * @Description:
 */
@Slf4j
@Service("asyncIpService")
public class AsyncIpServiceImpl implements AsyncIpService {

    @Autowired
    TOrgRepository tOrgRepository;

    @Autowired
    OrgIpRepository orgIpRepository;

    @Override
    public void asyncIp() {
        List<String> ipRangeList = new ArrayList<>();
        tOrgRepository.findAll().forEach(torg -> {
            Arrays.stream(torg.getIpRanges().split(";")).forEach(ipRange -> {
                String[] ipR = ipRange.split("---");
                String begin = ipR[0];
                String end = ipR[1];
                BigInteger beginNum = NetUtil.ipToBigInteger(ipR[0]);
                BigInteger endNum = NetUtil.ipToBigInteger(ipR[1]);
                if (beginNum.compareTo(endNum) > 0){
                    begin = ipR[1];
                    end = ipR[0];
                }
                if (!orgIpRepository.findByBeginAndEnd(begin,end).isPresent()){
                    ipRangeList.add(ipRange);
                }
            });
        });
        log.info("待同步量： {}",ipRangeList.size());
    }


    @Override
    public Map<OrgIpDTO, Set<OrgIp>> overlay() {
        List<OrgIp> orgIps = orgIpRepository.findAll();
        Map<OrgIpDTO, Set<OrgIp>> orgIpMap = new HashMap<>();
        for (int i = 0; i < orgIps.size(); i++) {
            OrgIp orgIp1 = orgIps.get(i);
            boolean isV6 = IPAddressUtil.isIPv6LiteralAddress(orgIp1.getBegin());
            BigInteger beginIp1 = NetUtil.ipToBigInteger(orgIp1.getBegin());
            BigInteger endIp1 = NetUtil.ipToBigInteger(orgIp1.getEnd());
            for (int j = i + 1; j < orgIps.size(); j++) {
                OrgIp orgIp2 = orgIps.get(j);
                BigInteger beginIp2 = NetUtil.ipToBigInteger(orgIp2.getBegin());
                BigInteger endIp2 = NetUtil.ipToBigInteger(orgIp2.getEnd());
                if (beginIp1.compareTo(beginIp2) > 0) {
                    beginIp2 = beginIp1;
                }
                if (endIp1.compareTo(endIp2) < 0) {
                    endIp2 = endIp1;
                }
                if (beginIp2.compareTo(endIp2) < 0) {
                    OrgIpDTO orgIpDTOKey = new OrgIpDTO();
                    orgIpDTOKey.setBegin(NetUtil.bigIntegerToIp(beginIp2, isV6)).setEnd(NetUtil.bigIntegerToIp(endIp2, isV6));
                    if (orgIpMap.get(orgIpDTOKey) != null) {
                        orgIpMap.get(orgIpDTOKey).add(orgIp1);
                        orgIpMap.get(orgIpDTOKey).add(orgIp2);
                    } else {
                        Set<OrgIp> ips = new HashSet<>();
                        ips.add(orgIp1);
                        ips.add(orgIp2);
                        orgIpMap.put(orgIpDTOKey, ips);
                    }
                }
            }
        }
        Console.log(JSONUtil.parseFromMap(orgIpMap));
        return orgIpMap;
    }
}
